package app.component;

import java.awt.Desktop;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JToolBar;

import app.gif.ExportProperties;
import app.gif.FrameProcessor;
import app.util.Utils;
import chrriis.dj.nativeswing.swtimpl.components.JFlashPlayer;

/**
 * @author Evstigneev Kirill (kester)
 */
public class ImageAnimatorToolbar extends JToolBar {

	private static final String RES_OPEN_FOLDER_24_PNG = "res/open_folder_24.png";
	private static final String RES_CAPTURE_24_PNG = "res/capture_24.png";
	private static final String RES_PROCESS_ACCEPT_24_PNG = "res/process_accept_24.png";

	private final ImageAnimator parent;
	private final JFlashPlayer flashPlayer;
	private final FrameProcessor frameProcessor;
	private final StatusBar statusBar;
	private String projectName;

	public ImageAnimatorToolbar( final ImageAnimator parent, final JFlashPlayer flashPlayer, final StatusBar statusBar ) {
		this.parent = parent;
		this.flashPlayer = flashPlayer;
		this.frameProcessor = new FrameProcessor();
		this.statusBar = statusBar;
	}

	public void init() {
		add( createLoadButton() );
		addSeparator();
		add( createScreenShotButton() );
		addSeparator();
		add( createProcessButton() );
		setVisible( true );
		setFloatable( false );
	}

	private JButton createLoadButton() {
		final JButton button = Utils.createButton( RES_OPEN_FOLDER_24_PNG, "Load SWF file..." , new ActionListener() {

			@Override
			public void actionPerformed(final ActionEvent e) {
				JFileChooser fc = new JFileChooser();
				fc.setDialogType(JFileChooser.OPEN_DIALOG);
				int result = fc.showOpenDialog(parent);
				if ( result == JFileChooser.APPROVE_OPTION ) {
					final File f = fc.getSelectedFile();
					final String path = f.getAbsolutePath();
					flashPlayer.load(path);

					projectName = f.getName();
					frameProcessor.clear();
					statusBar.reset();
				}
			}
		});
		return button;
	}

	private JButton createProcessButton() {
		final JButton button = Utils.createButton( RES_PROCESS_ACCEPT_24_PNG, "Process frames...", new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent e) {
				if( frameProcessor.getFrameCount() == 0 ) {
					JOptionPane.showMessageDialog( parent,
							"Make at least one shot",
							"Processing",
							JOptionPane.ERROR_MESSAGE );
					return;
				}
				final ProcessingPropertiesPanel ppp = new ProcessingPropertiesPanel(projectName);
				ppp.addWindowListener(new WindowAdapter() {
					@Override
					public void windowDeactivated(final WindowEvent e) {
						if( ppp != null && !ppp.isVisible() && ppp.isOkPressed() ) {
							statusBar.indicateProcess(true);
							final ExportProperties exportProperties = ppp.getExportProperties();
							final Thread t = new Thread() {
								@Override
								public void run() {
									frameProcessor.toGif( exportProperties );
									frameProcessor.createPreview( exportProperties );

									JOptionPane.showMessageDialog( parent,
															"Frames were successfully processed",
															"Processing",
															JOptionPane.INFORMATION_MESSAGE );

									statusBar.indicateProcess(false);
									if ( Desktop.isDesktopSupported() ) {
										try {
											Desktop.getDesktop().open( new File(exportProperties.getPath()) );
										} catch (Exception e) {
											//ignore
										}
									}
								};
							};
							t.start();
						}
					}
				});
				ppp.setVisible(true);
				Utils.centerFrame( parent, ppp );
			}
		});
		return button;
	}

	private JButton createScreenShotButton() {
		final JButton button = Utils.createButton( RES_CAPTURE_24_PNG, "Capture the frame", new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent e) {
				try {
					statusBar.indicateProcess(true);
					takeScreenShot();
					statusBar.addFrame();
					statusBar.indicateProcess(false);
				} catch ( Exception ex ) {
					statusBar.indicateProcess(false);
					ex.printStackTrace();
				}
			}
		});
		button.setMnemonic(KeyEvent.VK_S);
		return button;
	}

	private void takeScreenShot() throws Exception {
		final Robot robot = new Robot();
		final Rectangle rect = new Rectangle( flashPlayer.getSize() );

		final Point parentLocation = parent.getLocation();
		final Point fpLocation = flashPlayer.getLocation();

		rect.setLocation( new Double(parentLocation.getX() + fpLocation.getX()).intValue() + 7,
						  new Double(parentLocation.getY() + fpLocation.getY()).intValue() + getHeight() );

		final BufferedImage screenCapture = robot.createScreenCapture( rect );
		frameProcessor.addFrame( screenCapture );
	}

	public void updateProjectName( final String projectName ) {
		this.projectName = projectName;
	}

}
